<template>
  <div>
    <h2>浅拷贝</h2>
    <h3>Object.assign()</h3>
    <div class="box">
      <div class="origin">
        原始数据：
        <ol style="color: #2f54eb">
          <li>{{ script.title }}</li>
          <li>{{ script.stars }}</li>
          <li>{{ script.author.name }}</li>
        </ol>
      </div>

      <div class="copy">
        拷贝数据：
        <ol style="color: #eb2f96">
          <li>{{ copyScript ? copyScript.title : "" }}</li>
          <li>{{ copyScript ? copyScript.stars : "" }}</li>
          <li>{{ copyScript ? copyScript.author.name : "" }}</li>
        </ol>
      </div>
    </div>
    <button @click="copy1">拷贝</button>

    <h3>扩展运算符...</h3>
    <div class="box">
      <div class="origin">
        原始数据：
        <ol style="color: #2f54eb">
          <li>{{ script.title }}</li>
          <li>{{ script.stars }}</li>
          <li>{{ script.author.name }}</li>
        </ol>
      </div>

      <div class="copy">
        拷贝数据：
        <ol style="color: #eb2f96">
          <li>{{ copyScript ? copyScript.title : "" }}</li>
          <li>{{ copyScript ? copyScript.stars : "" }}</li>
          <li>{{ copyScript ? copyScript.author.name : "" }}</li>
        </ol>
      </div>
    </div>
    <button @click="copy2">拷贝</button>

    <h3>数组slice、concat、扩展运算符</h3>
    <div class="box">
      <div class="origin">
        原始数据：
        {{ items }}
      </div>
      <div class="copy">
        拷贝数据：
        {{ items2 }}
      </div>
    </div>
    <button @click="copy3">slice</button>
    <button @click="copy4">concat</button>
    <button @click="copy5">扩展运算符</button>

    <h2>深拷贝</h2>
    <h3>JSON.parse(JSON.stringify(obj))</h3>
    <h3>递归实现深拷贝</h3>
    <div class="box">
      <div class="origin">
        原始数据：
        {{ obj }}
      </div>
      <div class="origin">
        拷贝数据：
        {{ target }}
      </div>
    </div>
    <button @click="deepClone">递归拷贝</button>

    <div>
      <ol>
        <li>1、独立函数中：this指向全局对象</li>
        <li>2、严格模式下：this指向undefined</li>
      </ol>
    </div>
  </div>
</template>

<script lang="ts">
import { deepClone } from "@/common/util";
import { defineComponent, ref } from "vue";

interface AuthorType {
  name: string;
}

interface ScriptType {
  title: string;
  stars: number;
  author: AuthorType;
}

interface WorkType {
  title: string;
}

interface WorkerType {
  name: string;
  work: WorkType;
}
export default defineComponent({
  setup(props, context) {
    // 在这里声明数据，或者编写函数并在这里执行它
    // 通过响应式 API 创建的变量具备了响应性
    const author = ref<AuthorType>({ name: "李白" })

    const msg = ref<string>("passed");
    const script = ref<ScriptType>({
      title: "东方不败",
      stars: 100,
      author: {
        name: "王哈哈",
      },
    });
    const copyScript = ref<ScriptType>();
    const items = ref<any[]>([1, 2, [3, 4]]);
    const items2 = ref<any[]>([]);
    const target = ref<WorkerType>();
    const obj = ref<WorkerType>({
      name: "洪典典",
      work: {
        title: "后端工程师",
      },
    });

    return {
      // 需要给 `<template />` 用的数据或函数，在这里 `return` 出去
      author,
      msg,
      script,
      copyScript,
      items,
      items2,
      target,
      obj,
    };
  },
  data() {
    return {};
  },
  methods: {
    copy1() {
      this.copyScript = Object.assign({}, this.script);
      this.copyScript.title = "东方不败1";
      this.copyScript.author.name = "susan1";

      // 基本属性会保持不变，引用类型会变
      this.script.title = "东方不败2";
      this.script.author.name = "susan2";
    },
    copy2() {
      this.copyScript = { ...this.script };
      this.copyScript.title = "东方不败1";
      this.copyScript.author.name = "susan1";

      // 基本属性会保持不变，引用类型会变
      this.script.title = "东方不败2";
      this.script.author.name = "susan2";
    },
    copy3() {
      this.items2 = this.items.slice(1);

      // 改变原始数据
      this.items[1] = 888;
      this.items[2][0] = 555;
    },
    copy4() {
      this.items2 = this.items.concat(this.items);
      this.items[1] = 111;
      this.items[2][0] = 222;

      this.items2[2][0] = 444;
    },
    copy5() {
      this.items2 = [...this.items];
      this.items[1] = 666;
      this.items[2][0] = 777;
    },
    deepClone() {
      this.target = deepClone(this.obj);
      // this.target.name = "绿点点";
    },
  },
});
</script>

<style scoped>
.origin,
.copy {
  padding: 10px;
}
.origin {
  color: #2f54eb;
}

.copy {
  color: #eb2f96;
}

h3 {
  margin: 10px 0;
  padding: 10px 20px;
  background-color: rgba(0, 0, 0, 0.1);
}

.box {
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
}

button {
  background-color: rgba(47, 84, 235, 0.8);
  color: white;
  margin: 0 5px;
  padding: 10px 15px;
  border-radius: 2px;
  border: none;
}
</style>
